]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Layout: show the OSK on the monitor where the focused window lives
authorGiovanni Campagna <gcampagna@src.gnome.org>
Sun, 14 Oct 2012 16:57:45 +0000 (18:57 +0200)
committerGiovanni Campagna <gcampagna@src.gnome.org>
Tue, 20 Nov 2012 16:57:24 +0000 (17:57 +0100)
In multimonitor scenarios, it makes sense to show the OSK close to
the window that will actually receive keystrokes.

https://bugzilla.gnome.org/show_bug.cgi?id=685856

js/ui/keyboard.js
js/ui/layout.js
js/ui/messageTray.js

index 482fb30684136a622e7ec9b91b182b3f2fa6e3a9..67f00ba34ff32107accec1e556bc035a796627af 100644 (file)
@@ -251,7 +251,7 @@ const Keyboard = new Lang.Class({
         this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
 
         if (show)
-            this.show();
+            this.show(Main.layoutManager.focusIndex);
         else
             this._createSource();
     },
@@ -375,7 +375,7 @@ const Keyboard = new Lang.Class({
         if (!this._enableKeyboard)
             return;
 
-        let monitor = Main.layoutManager.bottomMonitor;
+        let monitor = Main.layoutManager.keyboardMonitor;
         let maxHeight = monitor.height / 3;
         this.actor.width = monitor.width;
 
@@ -462,9 +462,9 @@ const Keyboard = new Lang.Class({
                actor._extended_keys || actor.extended_key;
     },
 
-    show: function () {
+    show: function (monitor) {
+        Main.layoutManager.keyboardIndex = monitor;
         this._redraw();
-
         Main.layoutManager.showKeyboard();
         this._destroySource();
     },
@@ -512,7 +512,7 @@ const Keyboard = new Lang.Class({
 
         if (timestamp != Clutter.CURRENT_TIME)
             this._timestamp = timestamp;
-        this.show();
+        this.show(Main.layoutManager.focusIndex);
     },
 
     Hide: function(timestamp) {
@@ -566,6 +566,7 @@ const KeyboardSource = new Lang.Class({
     },
 
     open: function() {
-        this._keyboard.show();
+        // Show the OSK below the message tray
+        this._keyboard.show(Main.layoutManager.bottomIndex);
     }
 });
index 0b3aa56f0e2d7eb0861c6a2c11a2022239b26d5d..a84a9b02fe0341f13908dd41f01b0461b2df8e2d 100644 (file)
@@ -103,6 +103,7 @@ const LayoutManager = new Lang.Class({
         this.monitors = [];
         this.primaryMonitor = null;
         this.primaryIndex = -1;
+        this._keyboardIndex = -1;
         this._hotCorners = [];
         this._background = null;
         this._leftPanelBarrier = 0;
@@ -240,9 +241,8 @@ const LayoutManager = new Lang.Class({
         this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
         this.panelBox.set_size(this.primaryMonitor.width, -1);
 
-        this.keyboardBox.set_position(this.bottomMonitor.x,
-                                      this.bottomMonitor.y + this.bottomMonitor.height);
-        this.keyboardBox.set_size(this.bottomMonitor.width, -1);
+        if (this.keyboardIndex < 0)
+            this.keyboardIndex = this.primaryIndex;
 
         this.trayBox.set_position(this.bottomMonitor.x,
                                   this.bottomMonitor.y + this.bottomMonitor.height);
@@ -305,6 +305,42 @@ const LayoutManager = new Lang.Class({
         return this.monitors[index];
     },
 
+    get keyboardMonitor() {
+        return this.monitors[this.keyboardIndex];
+    },
+
+    get focusIndex() {
+        let i = Main.layoutManager.primaryIndex;
+
+        if (global.stage_input_mode == Shell.StageInputMode.FOCUSED ||
+            global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) {
+            let focusActor = global.stage.key_focus;
+            if (focusActor)
+                i = this._chrome.findIndexForActor(focusActor);
+        } else {
+            let focusWindow = global.display.focus_window;
+            if (focusWindow)
+                i = this._chrome.findIndexForWindow(focusWindow.get_compositor_private());
+        }
+
+        return i;
+    },
+
+    get focusMonitor() {
+        return this.monitors[this.focusIndex];
+    },
+
+    set keyboardIndex(v) {
+        this._keyboardIndex = v;
+        this.keyboardBox.set_position(this.keyboardMonitor.x,
+                                      this.keyboardMonitor.y + this.keyboardMonitor.height);
+        this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
+    },
+
+    get keyboardIndex() {
+        return this._keyboardIndex;
+    },
+
     _startupAnimation: function() {
         this.panelBox.anchor_y = this.panelBox.height;
 
@@ -363,11 +399,14 @@ const LayoutManager = new Lang.Class({
                            onComplete: this._showKeyboardComplete,
                            onCompleteScope: this
                          });
-        Tweener.addTween(this.trayBox,
-                         { anchor_y: this.keyboardBox.height,
-                           time: KEYBOARD_ANIMATION_TIME,
-                           transition: 'easeOutQuad'
-                         });
+
+        if (this.keyboardIndex == this.bottomIndex) {
+            Tweener.addTween(this.trayBox,
+                             { anchor_y: this.keyboardBox.height,
+                               time: KEYBOARD_ANIMATION_TIME,
+                               transition: 'easeOutQuad'
+                             });
+        }
 
         this.emit('keyboard-visible-changed', true);
     },
@@ -379,7 +418,8 @@ const LayoutManager = new Lang.Class({
 
         this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
             this.keyboardBox.anchor_y = this.keyboardBox.height;
-            this.trayBox.anchor_y = this.keyboardBox.height;
+            if (this.keyboardIndex == this.bottomIndex)
+                this.trayBox.anchor_y = this.keyboardBox.height;
         }));
     },
 
@@ -395,11 +435,14 @@ const LayoutManager = new Lang.Class({
                            onComplete: this._hideKeyboardComplete,
                            onCompleteScope: this
                          });
-        Tweener.addTween(this.trayBox,
-                         { anchor_y: 0,
-                           time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
-                           transition: 'easeOutQuad'
-                         });
+
+        if (this.keyboardIndex == this.bottomIndex) {
+            Tweener.addTween(this.trayBox,
+                             { anchor_y: 0,
+                               time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
+                               transition: 'easeOutQuad'
+                             });
+        }
 
         this.emit('keyboard-visible-changed', false);
     },
@@ -463,7 +506,7 @@ const LayoutManager = new Lang.Class({
     },
 
     findMonitorForActor: function(actor) {
-        return this._chrome.findMonitorForActor(actor);
+        return this.monitors[this._chrome.findIndexForActor(actor)];
     }
 });
 Signals.addSignalMethods(LayoutManager.prototype);
@@ -812,6 +855,7 @@ const Chrome = new Lang.Class({
 
     _relayout: function() {
         this._monitors = this._layoutManager.monitors;
+        this._primaryIndex = this._layoutManager.primaryIndex;
         this._primaryMonitor = this._layoutManager.primaryMonitor;
 
         this._updateFullscreen();
@@ -827,32 +871,47 @@ const Chrome = new Lang.Class({
             let monitor = this._monitors[i];
             if (cx >= monitor.x && cx < monitor.x + monitor.width &&
                 cy >= monitor.y && cy < monitor.y + monitor.height)
-                return monitor;
+                return i;
         }
         // If the center is not on a monitor, return the first overlapping monitor
         for (let i = 0; i < this._monitors.length; i++) {
             let monitor = this._monitors[i];
             if (x + w > monitor.x && x < monitor.x + monitor.width &&
                 y + h > monitor.y && y < monitor.y + monitor.height)
-                return monitor;
+                return i;
         }
         // otherwise on no monitor
-        return null;
+        return -1;
     },
 
-    _findMonitorForWindow: function(window) {
-        return this._findMonitorForRect(window.x, window.y, window.width, window.height);
+    findIndexForWindow: function(window) {
+        let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
+        if (i >= 0)
+            return i;
+        return this._primaryIndex; // Not on any monitor, pretend its on the primary
     },
 
     // This call guarantees that we return some monitor to simplify usage of it
     // In practice all tracked actors should be visible on some monitor anyway
-    findMonitorForActor: function(actor) {
+    findIndexForActor: function(actor) {
         let [x, y] = actor.get_transformed_position();
         let [w, h] = actor.get_transformed_size();
-        let monitor = this._findMonitorForRect(x, y, w, h);
-        if (monitor)
-            return monitor;
-        return this._primaryMonitor; // Not on any monitor, pretend its on the primary
+        let i = this._findMonitorForRect(x, y, w, h);
+        if (i >= 0)
+            return i;
+        return this._primaryIndex; // Not on any monitor, pretend its on the primary
+    },
+
+    findMonitorForWindow: function(window) {
+        let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
+        if (i >= 0)
+            return this._monitors[i];
+        else
+            return null;
+    },
+
+    findMonitorForActor: function(actor) {
+        return this._monitors[this.findIndexForActor(actor)];
     },
 
     _queueUpdateRegions: function() {
@@ -900,7 +959,7 @@ const Chrome = new Lang.Class({
                 continue;
 
             if (layer == Meta.StackLayer.FULLSCREEN) {
-                let monitor = this._findMonitorForWindow(window);
+                let monitor = this.findMonitorForWindow(window);
                 if (monitor)
                     monitor.inFullscreen = true;
             }
@@ -917,7 +976,7 @@ const Chrome = new Lang.Class({
                 }
 
                 // Or whether it is monitor sized
-                let monitor = this._findMonitorForWindow(window);
+                let monitor = this.findMonitorForWindow(window);
                 if (monitor &&
                     window.x <= monitor.x &&
                     window.x + window.width >= monitor.x + monitor.width &&
index fa1ea31d060c758ac65a567799fd5d8211baafd7..483b71dc4b1426d83677a7f1c74a79f821846123 100644 (file)
@@ -1471,6 +1471,7 @@ const MessageTray = new Lang.Class({
         this._pointerInTray = false;
         this._pointerInKeyboard = false;
         this._keyboardVisible = false;
+        this._keyboardUnderMessageTray = false;
         this._summaryState = State.HIDDEN;
         this._pointerInSummary = false;
         this._notificationClosed = false;
@@ -1924,12 +1925,15 @@ const MessageTray = new Lang.Class({
     },
 
     _onKeyboardVisibleChanged: function(layoutManager, keyboardVisible) {
-        if (this._keyboardVisible == keyboardVisible)
+        let keyboardUnderMessageTray = layoutManager.keyboardIndex == layoutManager.bottomIndex;
+        if (this._keyboardVisible == keyboardVisible &&
+            this._keyboardUnderMesssageTray == keyboardUnderMessageTray)
             return;
 
         this._keyboardVisible = keyboardVisible;
+        this._keyboardUnderMessageTray = keyboardUnderMessageTray;
 
-        if (keyboardVisible)
+        if (keyboardVisible && keyboardUnderMessageTray)
             this.actor.add_style_pseudo_class('keyboard');
         else
             this.actor.remove_style_pseudo_class('keyboard');
@@ -2086,12 +2090,12 @@ const MessageTray = new Lang.Class({
                                      this._desktopCloneState == State.SHOWN);
         let desktopCloneShouldBeVisible = (trayShouldBeVisible &&
                                            !this._overviewVisible &&
-                                           !this._keyboardVisible);
+                                           (!this._keyboardVisible || !this._keyboardUnderMessageTray));
 
         if (!desktopCloneIsVisible && desktopCloneShouldBeVisible) {
             this._showDesktopClone();
         } else if (desktopCloneIsVisible && !desktopCloneShouldBeVisible) {
-            this._hideDesktopClone (this._keyboardVisible);
+            this._hideDesktopClone (this._keyboardVisible && this._keyboardUnderMessageTray);
         }
     },